package com.yunji.order.command.order.impl;

import com.yunji.base.enums.ScaleBelongTypeEnum;
import com.yunji.cabinet.device.DeviceCommandEngine;
import com.yunji.cabinet.device.DeviceCommandEnum;
import com.yunji.cabinet.device.DeviceEventEnum;
import com.yunji.cabinet.dto.device.DeviceCommandDTO;
import com.yunji.cabinet.dto.device.DeviceEventDTO;
import com.yunji.cabinet.dto.device.DeviceShoppingDTO;
import com.yunji.common.event.EventConstant;
import com.yunji.common.event.RedissonEventBus;
import com.yunji.common.event.SpringEventBus;
import com.yunji.common.event.entity.EventData;
import com.yunji.common.event.entity.RedissonEvent;
import com.yunji.common.utils.JsonUtil;
import com.yunji.common.utils.TimeUtils;
import com.yunji.coupon.dto.OrderScaleDTO;
import com.yunji.order.command.order.AbsOrderCommand;
import com.yunji.order.context.convert.OrderConvert;
import com.yunji.order.context.engine.OrderCalculate;
import com.yunji.order.context.engine.OrderCellCalculate;
import com.yunji.order.domain.OrderDO;
import com.yunji.order.domain.OrderDetailDO;
import com.yunji.order.domain.OrderOrdinalDO;
import com.yunji.order.dto.cmd.OrderPaidCommandDTO;
import com.yunji.order.emuns.AckStatus;
import com.yunji.order.emuns.OrderStatusEnum;
import com.yunji.order.event.OrderScaleEvent;
import com.yunji.order.wechat.WechatCallbackDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author : peter-zhu
 * @date : 2025/3/7 13:52
 * @description : TODO
 **/
@Component
@Slf4j
public class OrderPaidCommand extends AbsOrderCommand<OrderPaidCommandDTO, Boolean> {

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean execute(OrderPaidCommandDTO cmd) {
        log.info("【微信支付回调】支付信息:{}", cmd);
        WechatCallbackDTO callback = cmd.getCallbackDTO();
        OrderDO order = cmd.getOrderDO();
        // ack 代表设备是否收到你的指令 会更新到订单 一看订单就知道此订单的设备ACK有没有收到
        boolean ack = false;
        DeviceEventDTO deviceEventDTO = null;
        List<OrderDetailDO> orderDetails = orderService.getOrderDetailsByOid(order.getOrderId());
        try {
            List<OrderOrdinalDO> purchase = OrderCellCalculate.purchase(order.getChipImei(), orderDetails);
            orderService.saveOrderOrdinals(purchase);
            List<DeviceShoppingDTO> shoppingList = purchase.stream().map(a ->
                    new DeviceShoppingDTO(a.getOrdinal(), a.getProductNums())).collect(Collectors.toList());
            deviceEventDTO = new DeviceEventDTO(order.getOrderCode(), order.getOrderId(), null,
                    new DeviceCommandDTO(DeviceEventEnum.ORDER.name(), DeviceCommandEnum.OPEN_SHIPPING.name(), order.getChipImei(), shoppingList));
            deviceEventDTO.setMemberId(order.getMemberId());
            ack = DeviceCommandEngine.executeEvent(deviceEventDTO);
            //FIXME 先循环调
            for (OrderOrdinalDO ordinalDO : purchase) {
                orderConsumer.updateCabinetCell(ordinalDO.getProductNums(), ordinalDO.getOrdinal(),
                        order.getContainerId(), 1);
            }

        } catch (Exception e) {
            log.error("OrderPaidCommand DeviceCommandEngine executeEvent error data:{}", JsonUtil.toJsonString(deviceEventDTO), e);
        }
        String wechatPayCode = callback.getWechatCode();
        Date payTime = TimeUtils.parseZoneDate(callback.getTime());
        // 计算分润
        Map<ScaleBelongTypeEnum, OrderScaleDTO> scaleMap = OrderCalculate.calculateOrderScale(order);
        OrderDO updateOrder = new OrderDO();
        updateOrder.setOrderId(order.getOrderId());
        updateOrder.setPayCode(wechatPayCode);
        updateOrder.setPayTime(payTime);
        updateOrder.setAck(ack ? AckStatus.RECEIVED.getCode() : AckStatus.INIT.getCode());
        updateOrder.setOrderStatus(OrderStatusEnum.PAY_SUCCESS.getCode());
        updateOrder.setPlateAmt(scaleMap.get(ScaleBelongTypeEnum.PLATE).getAmt());
        updateOrder.setAgentAmt(scaleMap.get(ScaleBelongTypeEnum.AGENT).getAmt());
        updateOrder.setSiteAmt(scaleMap.get(ScaleBelongTypeEnum.SITE).getAmt());
        boolean b = orderService.updateOrder(updateOrder);
        if (b) {
            // 发送分润事件 如果分润失败 订单依然支付成功 订单有个分润状态代表订单是否分润成功
            SpringEventBus.getInstance().publish(new EventData<>(new OrderScaleEvent(order, scaleMap, wechatPayCode, payTime)));
            //【购买商品】解冻金额的延迟队列
            redissonQueue.setScaleQueue(order);
            //【购买商品】延时处理发货信息
            redissonQueue.setDeliveredQueue(order);
        }
        order.setPayTime(updateOrder.getPayTime());
        RedissonEventBus.getInstance().publishAsync(new RedissonEvent<>(EventConstant.ORDER_VISUAL_QUEUE_KEY,
                OrderConvert.convertQueueDTO(order, orderDetails)));
        return b;
    }

}